import RectType from "./RectType.js";
export default class AStarManager {
    constructor(map) {
        this.openList = new Array();
        this.closeList = new Array();
        this.map = null;
        this.mapWidth = 0;
        this.mapHeight = 0;
        if (!AStarManager.Instance) {
            AStarManager.Instance = this;
        }
        AStarManager.Instance.map = map;
        this.mapWidth = map.length;
        this.mapHeight = map[0].length;
        return AStarManager.Instance;
    }
    calc(start, end) {
        // 是否有地界数据
        if (!this.map)
            return null;
        // 是否超出边界
        // if(start.x < 0 || start.x >= Map.length || start.y )
        // 重置数据
        this.openList = new Array();
        this.closeList = new Array();
        // this.openList.push(start)
        // 开始查找
        while (true) {
            // 把开始点加入 closeList
            this.closeList.push(start);
            // 查找周围的 方块
            this.findNearRectToOpenList(start, end);
            // 如果找不到相邻方块为死路
            if (this.openList.length == 0) {
                console.log('死路');
                return null;
            }
            // 如果有可以通过的相邻方块，找出消耗最小的一个
            this.openList.sort(sortBy);
            start = this.openList.pop();
            // 如果到达终点
            if (start == end) {
                const path = new Array();
                path.push(end);
                while (end.parent !== null) {
                    path.push(end.parent);
                    end = end.parent;
                }
                return path.reverse();
            }
        }
    }
    findNearRectToOpenList(start, end) {
        if (!this.map)
            return;
        const x = start.x;
        const y = start.y;
        // 上
        this.addToOpenList(x, y - 1, start, end);
        // 下
        this.addToOpenList(x, y + 1, start, end);
        // 左
        this.addToOpenList(x - 1, y, start, end);
        // 右
        this.addToOpenList(x + 1, y, start, end);
    }
    addToOpenList(x, y, start, end) {
        if (!this.map)
            return;
        // 不在地图范围内的不用计算
        if (x < 0 || y < 0
            || x >= this.mapWidth || y >= this.mapHeight) {
            return;
        }
        const rect = this.map[x][y];
        // 如果已经计算过了，就不用重新计算f(消耗)值了
        if (this.openList.includes(rect) || this.closeList.includes(rect) || rect.type == RectType.Obstacles)
            return;
        rect.parent = start;
        rect.g = rect.parent.g + 1;
        rect.h = Math.abs(end.x - x) + Math.abs(end.y - y);
        rect.f = rect.g + rect.h;
        this.openList.push(rect);
    }
}
function sortBy(a, b) {
    return b.f - a.f;
}
